package com.hdq.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.hdq.constant.MessageConstant;
import com.hdq.exception.*;
import com.hdq.mapper.ImageMapper;
import com.hdq.result.PageResult;
import com.hdq.service.ImageService;
import com.hdq.utils.AliOssUtil;
import dto.ImageAddDTO;
import dto.ImageEditDTO;
import entity.Image;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import vo.ImageUploadVO;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.UUID;

@Service
@Slf4j
public class ImageServiceImpl implements ImageService {

    @Autowired
    private AliOssUtil aliOssUtil;
    @Autowired
    private ImageMapper imageMapper;

    // 允许上传的图片类型的后缀集合
    static final Set<String> imageSuffix = Set.of("jpg", "jpeg", "gif", "png", "webp");

    @Override
    public List<ImageUploadVO> upload(MultipartFile[] files) {
        List<ImageUploadVO> lists = new ArrayList<>();
        for (MultipartFile file : files) {
            // 文件的原始名称
            String fileName = file.getOriginalFilename();
            if (fileName == null) {
                throw new FileNameIsNullException(MessageConstant.FILE_NAME_NOT_NULL);
            }

            // 解析出文件后缀
            int index = fileName.lastIndexOf(".");
            if (index == -1) {
                throw new FileSuffixIsNullException(MessageConstant.FILE_SUFFIX_NOT_NULL);
            }

            String suffix = fileName.substring(index + 1);

            if (!imageSuffix.contains(suffix.trim().toLowerCase())) {
                throw new IllegalFileTypeException(MessageConstant.ILLEGAL_FILE_TYPES);
            }
            try {
                String object_name = UUID.randomUUID() + "." + suffix;
                String uploadString = aliOssUtil.upload(file.getBytes(), object_name);
                ImageUploadVO imageUploadVO = new ImageUploadVO();
                imageUploadVO.setName(fileName);
                imageUploadVO.setUrl(uploadString);
                imageUploadVO.setPath(null);
                lists.add(imageUploadVO);
            } catch (IOException e) {
                log.error(MessageConstant.UPLOAD_FAILED + "：" + e.getMessage());
            }
        }
        return lists;
    }

    @Override
    public void insertPictureByCategory(Long imageClassId, List<ImageAddDTO> imageAddDTOS) {
        if (imageClassId == null || imageClassId == 0) {
            throw new CategoryIdNotNullException(MessageConstant.CATEGORY_ID_IS_NULL);
        }
        List<Image> imageList = new ArrayList<>();
        for (ImageAddDTO imageAddDTO : imageAddDTOS) {
            Image image = new Image();
            BeanUtils.copyProperties(imageAddDTO, image);
            String name = image.getName().substring(0, image.getName().lastIndexOf("."));
            image.setName(name);
            image.setImageClassId(imageClassId);
            imageList.add(image);
        }
        imageMapper.insertPictureByCategory(imageList);
    }


    @Override
    public PageResult getImageByCategory(Long imageId, Integer limit, Integer page) {
        PageHelper.startPage(page, limit);
        Page<Image> imageList = imageMapper.getImageByCategory(imageId);
        return new PageResult(imageList.getTotal(), imageList.getResult());
    }

    @Override
    @Transactional
    public void deleteImage(Integer id, String filename) {
        try {
            //        删除图片
            imageMapper.deleteImage(id);
            //        删除远端服务器图片
            aliOssUtil.delete(filename);

        } catch (Exception e) {
            throw new OssFileDeleteException(MessageConstant.OSS_FILE_DELETE_FAIL);
        }
    }

    @Override
    public void updateImage(ImageEditDTO imageEditDTO) {
        imageMapper.updateImage(imageEditDTO);
    }
}
